﻿#include "DX3RootSingtureManager.h"

void DX3RootSingtureManager::BuildRootSignature(ID3D12Device* device)
{
    BuildDefaultRootSignature(device);
}

Microsoft::WRL::ComPtr<ID3D12RootSignature> DX3RootSingtureManager::GetRootSignature(RootSignatureType type)
{
    Microsoft::WRL::ComPtr<ID3D12RootSignature> rootSignature = nullptr;

    if(mRootSignatures.find(type) != mRootSignatures.end())
    {
        rootSignature = mRootSignatures[type];
    }

    return rootSignature;
}

void DX3RootSingtureManager::BuildDefaultRootSignature(ID3D12Device* device)
{
    CD3DX12_DESCRIPTOR_RANGE texTable;
    texTable.Init(D3D12_DESCRIPTOR_RANGE_TYPE_SRV, 4, 0, 0);
    
    CD3DX12_ROOT_PARAMETER slotRootParameter[4];

    slotRootParameter[0].InitAsConstantBufferView(0);
    slotRootParameter[1].InitAsConstantBufferView(1);
    slotRootParameter[2].InitAsShaderResourceView(0,1);
    slotRootParameter[3].InitAsDescriptorTable(1,&texTable,D3D12_SHADER_VISIBILITY_PIXEL);

    auto staticSamplers = GetStaticSamplers();

    // A root signature is an array of root parameters.
    CD3DX12_ROOT_SIGNATURE_DESC rootSigDesc(4, slotRootParameter,
        (UINT)staticSamplers.size(), staticSamplers.data(),
        D3D12_ROOT_SIGNATURE_FLAG_ALLOW_INPUT_ASSEMBLER_INPUT_LAYOUT);

    // create a root signature with a single slot which points to a descriptor range consisting of a single constant buffer
    Microsoft::WRL::ComPtr<ID3DBlob> serializedRootSig = nullptr;
    Microsoft::WRL::ComPtr<ID3DBlob> errorBlob = nullptr;
    HRESULT hr = D3D12SerializeRootSignature(&rootSigDesc, D3D_ROOT_SIGNATURE_VERSION_1,
        serializedRootSig.GetAddressOf(), errorBlob.GetAddressOf());

    if(errorBlob != nullptr)
    {
        ::OutputDebugStringA((char*)errorBlob->GetBufferPointer());
    }
    ThrowIfFailed(hr);

    Microsoft::WRL::ComPtr<ID3D12RootSignature>  RootSignature = nullptr;

    ThrowIfFailed(device->CreateRootSignature(
        0,
        serializedRootSig->GetBufferPointer(),
        serializedRootSig->GetBufferSize(),
        IID_PPV_ARGS(RootSignature.GetAddressOf())));

    mRootSignatures[RootSignatureType::Default] = RootSignature;
}
